// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraSettingValueDiscrete_Language.h"

#include "Internationalization/Culture.h"
#include "Internationalization/TextLocalizationManager.h"
#include "Messaging/CommonGameDialog.h"
#include "Messaging/CommonMessagingSubsystem.h"
#include "Player/LyraLocalPlayer.h"
#include "Settings/LyraSettingsShared.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraSettingValueDiscrete_Language)

#define LOCTEXT_NAMESPACE "Lyra"

static const int32 SettingSystemDefaultLanguageIndex = 0; // 系统默认语言索引

/**
 * 构造函数
 */
ULyraSettingValueDiscrete_Language::ULyraSettingValueDiscrete_Language()
{
}

/**
 * 初始化时调用
 */
void ULyraSettingValueDiscrete_Language::OnInitialized()
{
	Super::OnInitialized(); // 调用父类初始化方法

	const TArray<FString> AllCultureNames = FTextLocalizationManager::Get().GetLocalizedCultureNames(ELocalizationLoadFlags::Game); // 获取所有本地化文化名称
	for (const FString& CultureName : AllCultureNames) // 遍历所有文化名称
	{
		if (FInternationalization::Get().IsCultureAllowed(CultureName)) // 检查文化是否允许
		{
			AvailableCultureNames.Add(CultureName); // 添加可用的文化名称
		}
	}

	AvailableCultureNames.Insert(TEXT(""), SettingSystemDefaultLanguageIndex); // 在系统默认语言索引处插入空字符串
}

/**
 * 存储初始设置
 */
void ULyraSettingValueDiscrete_Language::StoreInitial()
{
	// ? // 空实现
}

/**
 * 应用设置时调用
 */
void ULyraSettingValueDiscrete_Language::OnApply()
{
	if (UCommonMessagingSubsystem* Messaging = LocalPlayer->GetSubsystem<UCommonMessagingSubsystem>()) // 获取通用消息子系统
	{
		Messaging->ShowConfirmation( // 显示确认对话框
			UCommonGameDialogDescriptor::CreateConfirmationOk( // 创建确认OK对话框描述符
			LOCTEXT("WarningLanguage_Title", "语言已更改"), // 标题
			LOCTEXT("WarningLanguage_Message", "您需要完全重启游戏才能使所有语言相关更改生效。") // 消息
			)
		);
	}
}

/**
 * 重置为默认值
 */
void ULyraSettingValueDiscrete_Language::ResetToDefault()
{
	SetDiscreteOptionByIndex(SettingSystemDefaultLanguageIndex); // 根据索引设置离散选项为系统默认
}

/**
 * 恢复到初始值
 */
void ULyraSettingValueDiscrete_Language::RestoreToInitial()
{
	if (ULyraSettingsShared* Settings = CastChecked<ULyraLocalPlayer>(LocalPlayer)->GetSharedSettings()) // 获取共享设置
	{
		Settings->ClearPendingCulture(); // 清除待处理文化
		NotifySettingChanged(EGameSettingChangeReason::RestoreToInitial); // 通知设置已更改
	}
}

/**
 * 根据索引设置离散选项
 */
void ULyraSettingValueDiscrete_Language::SetDiscreteOptionByIndex(int32 Index)
{
	if (ULyraSettingsShared* Settings = CastChecked<ULyraLocalPlayer>(LocalPlayer)->GetSharedSettings()) // 获取共享设置
	{
		if (Index == SettingSystemDefaultLanguageIndex) // 如果是系统默认语言索引
		{
			Settings->ResetToDefaultCulture(); // 重置为默认文化
		}
		else if (AvailableCultureNames.IsValidIndex(Index)) // 如果索引有效
		{
			Settings->SetPendingCulture(AvailableCultureNames[Index]); // 设置待处理文化
		}
		
		NotifySettingChanged(EGameSettingChangeReason::Change); // 通知设置已更改
	}
}

/**
 * 获取离散选项索引
 */
int32 ULyraSettingValueDiscrete_Language::GetDiscreteOptionIndex() const
{
	if (const ULyraSettingsShared* Settings = CastChecked<ULyraLocalPlayer>(LocalPlayer)->GetSharedSettings()) // 获取共享设置
	{
		if (Settings->ShouldResetToDefaultCulture()) // 如果应该重置为默认文化
		{
			return SettingSystemDefaultLanguageIndex; // 返回系统默认语言索引
		}

		// 我们优先使用待处理文化而不是当前文化，因为选项UI在应用之前更新待处理文化，我们需要UI反映该选择
		FString PendingCulture = Settings->GetPendingCulture(); // 获取待处理文化
		if (PendingCulture.IsEmpty()) // 如果待处理文化为空
		{
			if (Settings->IsUsingDefaultCulture()) // 如果使用默认文化
			{
				return SettingSystemDefaultLanguageIndex; // 返回系统默认语言索引
			}

			PendingCulture = FInternationalization::Get().GetCurrentCulture()->GetName(); // 获取当前文化名称
		}

		// 尝试查找完全匹配
		{
			const int32 ExactMatchIndex = AvailableCultureNames.IndexOfByKey(PendingCulture); // 查找完全匹配索引
			if (ExactMatchIndex != INDEX_NONE) // 如果找到完全匹配
			{
				return ExactMatchIndex; // 返回完全匹配索引
			}
		}

		// 尝试查找优先匹配（例如，允许"en-US"在UI中显示为"en"）
		const TArray<FString> PrioritizedPendingCultures = FInternationalization::Get().GetPrioritizedCultureNames(PendingCulture); // 获取优先文化名称
		for (int32 i = 0; i < AvailableCultureNames.Num(); ++i) // 遍历可用文化名称
		{
			if (PrioritizedPendingCultures.Contains(AvailableCultureNames[i])) // 如果包含优先文化
			{
				return i; // 返回索引
			}
		}
	}

	return 0; // 返回默认索引
}

/**
 * 获取离散选项
 */
TArray<FText> ULyraSettingValueDiscrete_Language::GetDiscreteOptions() const
{
	TArray<FText> Options; // 选项数组

	for (const FString& CultureName : AvailableCultureNames) // 遍历可用文化名称
	{
		if (CultureName == TEXT("")) // 如果是空字符串（系统默认）
		{
			const FCulturePtr SystemDefaultCulture = FInternationalization::Get().GetDefaultCulture(); // 获取系统默认文化
			if (ensure(SystemDefaultCulture)) // 确保系统默认文化有效
			{
				const FString& DefaultCultureDisplayName = SystemDefaultCulture->GetDisplayName(); // 获取默认文化显示名称
				FText LocalizedSystemDefault = FText::Format(LOCTEXT("SystemDefaultLanguage", "系统默认 ({0})"), FText::FromString(DefaultCultureDisplayName)); // 格式化本地化系统默认文本

				Options.Add(MoveTemp(LocalizedSystemDefault)); // 添加本地化系统默认文本
			}
		}
		else
		{
			FCulturePtr Culture = FInternationalization::Get().GetCulture(CultureName); // 获取文化
			if (ensureMsgf(Culture, TEXT("无法找到文化 '%s'!"), *CultureName)) // 确保文化有效
			{
				const FString CultureDisplayName = Culture->GetDisplayName(); // 获取文化显示名称
				const FString CultureNativeName = Culture->GetNativeName(); // 获取文化原生名称

				// 仅当名称不同时显示两个名称（避免重复）
				FString Entry = (!CultureNativeName.Equals(CultureDisplayName, ESearchCase::CaseSensitive)) // 检查名称是否不同
					? FString::Printf(TEXT("%s (%s)"), *CultureNativeName, *CultureDisplayName) // 格式化包含两个名称的条目
					: CultureNativeName; // 使用文化原生名称

				Options.Add(FText::FromString(Entry)); // 添加格式化文本
			}
		}
	}

	return Options; // 返回选项数组
}

#undef LOCTEXT_NAMESPACE